from debug import *

class Buffer():
    def __init__(self,buffer_size) -> None:
        self.buffer_size = buffer_size
        # 用list来实现lru的buffer,list的每个元素是一个数组，用于保存这个entry的状态。
        # 格式是(page_number,dirty),dirty=1表示为脏
        self.buffer = [] 
        self.entry_count = 0

    def is_hit(self,page_number):
        for entry in self.buffer:
            if page_number == entry[0]:
                #命中了说明这个数据是最近要用的，提到队尾
                self.buffer.remove(entry)
                self.buffer.append(entry)
                return True
        #没有命中过
        return False

    #返回True代表插入是没有开销的，False代表驱逐的是个脏页
    def allocate(self,page_number):
        # 注释掉的原因是不在里面判断是否命中了，由上层自己判断，否则返回值混乱
        # if self.is_hit(page_number):
        #     return False

        #先插进来再说
        self.buffer.append([page_number,0])
        self.entry_count += 1

        # 如果超出大小了，驱逐一个出来，并且判断是不是脏页
        if self.entry_count > self.buffer_size:
            #遍历查找没有正在使用的buffer
            #for entry in self.buffer:
            victim = self.buffer.pop(0)
            if victim[1]==1:
                return False
            else:
                return True

        return True
    
    #默认情况下是置脏位，因为写回是发生在驱逐出去后的，不会存在在buffer内却又不脏了的情况
    def mark_dirty(self,page_number,dirty_status=1):
        for i in range(len(self.buffer)):
            if page_number == self.buffer[i][0]:#找到了
                self.buffer[i][1] = dirty_status
                return True
        #没有找到
        return False